package com.pansoft.openplanet.widget;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import com.pansoft.openplanet.R;

/**
 * Created by will on 18-4-2.
 */


/**
 * ValueBar is a custom View for displaying values in an edgy bar.
 *
 * @author Philipp Jahoda
 */
public class TCValueBar extends View implements AnimatorUpdateListener {

    /** minimum value the bar can display */
    private float mMinVal = 0f;

    /** maximum value the bar can display */
    private float mMaxVal = 100f;

    /** the value the bar currently displays */
    private float mValue = 1f;

    /** the interval in which values can be chosen and displayed */
    private float mInterval = 1f;

    private int mColor = R.color.white;

    private RectF mBar;

    private Paint mBarPaint;
    private Paint mOverlayPaint;

    private ObjectAnimator mAnimator;



    public TCValueBar(Context context) {
        super(context);
        init();
    }

    public TCValueBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TCValueBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * Do all preparations.
     */
    private void init() {

        mBar = new RectF();
        mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPaint.setStyle(Paint.Style.FILL);


        mOverlayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mOverlayPaint.setStyle(Paint.Style.FILL);
        mOverlayPaint.setColor(Color.WHITE);
        mOverlayPaint.setAlpha(120);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        prepareBarSize();

        mBarPaint.setColor(getResources().getColor(mColor));

        // draw the value-bar
        canvas.drawRect(mBar, mBarPaint);

    }

    /**
     * Prepares the bar according to the current value.
     */
    private void prepareBarSize() {

        float length = ((float) getWidth() / (mMaxVal - mMinVal)) * (mValue - mMinVal);

        mBar.set(getWidth() - length, 0, getWidth(), getHeight());
    }

    /**
     * Sets the minimum and maximum value the bar can display.
     *
     * @param min
     * @param max
     */
    public void setMinMax(float min, float max) {
        mMaxVal = max;
        mMinVal = min;
    }

    public void setMax(float max) {
        mMaxVal = max;
    }

    /**
     * Returns the maximum value the bar can display.
     *
     * @return
     */
    public float getMax() {
        return mMaxVal;
    }

    /**
     * Returns the minimum value the bar can display.
     *
     * @return
     */
    public float getMin() {
        return mMinVal;
    }

    /**
     * Sets the actual value the bar displays. Do not forget to set a minimum
     * and maximum value.
     *
     * @param value
     */
    public void setValue(float value) {
        mValue = value;
    }

    /**
     * Returns the currently displayed value.
     *
     * @return
     */
    public float getValue() {
        return mValue;
    }

    /**
     * Sets the interval in which the values can be chosen and dispalyed from /
     * on the ValueBar. If interval <= 0, there is no interval.
     *
     * @param interval
     */
    public void setInterval(float interval) {
        mInterval = interval;
    }

    /**
     * Returns the interval in which values can be chosen and displayed.
     *
     * @return
     */
    public float getInterval() {
        return mInterval;
    }

    /**
     * Returns the bar that represents the value.
     *
     * @return
     */
    public RectF getBar() {
        return mBar;
    }

    /**
     * Animates the bar from a specific value to a specific value.
     *
     * @param from
     * @param to
     * @param durationMillis
     */
    public void animate(float from, float to, int durationMillis) {

        if (from < mMinVal)
            from = mMinVal;
        if (from > mMaxVal)
            from = mMaxVal;

        if (to < mMinVal)
            to = mMinVal;
        if (to > mMaxVal)
            to = mMaxVal;

        mValue = from;
        mAnimator = ObjectAnimator.ofFloat(this, "value", mValue, to);
        mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        mAnimator.setDuration(durationMillis);
        mAnimator.addUpdateListener(this);
        mAnimator.start();
    }

    /**
     * Animates the bar up from it's minimum value to the specified value.
     *
     * @param to
     * @param durationMillis
     */
    public void animateUp(float to, int durationMillis) {

        if (to > mMaxVal)
            to = mMaxVal;

        mAnimator = ObjectAnimator.ofFloat(this, "value", mValue, to);
        mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        mAnimator.setDuration(durationMillis);
        mAnimator.addUpdateListener(this);
        mAnimator.start();
    }

    /**
     * Animates the bar down from it's current value to the specified value.
     *
     * @param to
     * @param durationMillis
     */
    public void animateDown(float to, int durationMillis) {

        if (to < mMinVal)
            to = mMinVal;

        mAnimator = ObjectAnimator.ofFloat(this, "value", mValue, to);
        mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        mAnimator.setDuration(durationMillis);
        mAnimator.addUpdateListener(this);
        mAnimator.start();
    }

    @Override
    public void onAnimationUpdate(ValueAnimator va) {
        invalidate();
    }


    /**
     * Sets the color the ValueBar should have.
     *
     * @param color
     */
    public void setColor(int color) {
        mColor = color;
    }

    /**
     * Returns the paint object that is used for drawing the bar.
     *
     * @return
     */
    public Paint getBarPaint() {
        return mBarPaint;
    }

    /**
     * Sets the color of the overlay that is placed below the value-text.
     *
     * @param color
     */
    public void setOverlayColor(int color) {
        int alpha = mOverlayPaint.getAlpha();
        mOverlayPaint.setColor(color);
        mOverlayPaint.setAlpha(alpha);
    }


    /**
     * Returns the corresponding value for a pixel-position on the horizontal
     * axis.
     *
     * @param xPos
     * @return
     */
    public float getValueForPosition(int xPos) {

        float factor = xPos / getWidth();
        return mMaxVal * factor;
    }
}

